/*
 * Listas.cpp
 *
 *  Created on: 22/08/2012
 *      Author: vitorcasadei
 */

#include "Listas.h"

Listas::Listas(){
    iVacina = lVacinas.end();
    iDoenca = lDoencas.end();
    iCliente = lClientes.end();
    
    quantidadeVacinas = 0;
    quantidadeDoencas = 0;
    quantidadeClientes = 0;
}

void Listas::exibirTodosClientes(){
    
    for(list<Cliente>::iterator iterCliente = lClientes.begin(); iterCliente != lClientes.end(); iterCliente++)
        cout << (*iterCliente) << endl;
    
}

bool Listas::selecionarClientePos(int pos){
    
    if((iCliente = Pesquisa::pesquisarCliente(lClientes, pos)) == lClientes.end()){
        return false;
    }
     
    pacote.novoPacote();
    pacote.setCliente((*iCliente));
    return true;
}

bool Listas::selecionarCliente(string cpf){
    
    if((iCliente = Pesquisa::pesquisarClienteIter(lClientes, cpf)) == lClientes.end())
        return false;
        
    pacote.novoPacote();
    pacote.setCliente((*iCliente));
    return true;
}

bool Listas::selecionarVacina(int pk){
    
    if((iVacina = Pesquisa::pesquisarVacina(lVacinas, pk)) == lVacinas.end())
        return false;
        
    return true;
}

void Listas::inserirCliente(string nome, string cpf){
    lClientes.push_back(Cliente(nome, cpf));
    ++quantidadeClientes;
}

bool Listas::editarCliente(string novoNome, string novoCPF){
    
    //Verifica se já existe o mesmo cpf cadastrado ou se nenhum cliente foi selecionado.
    if(Pesquisa::pesquisarClienteIter(lClientes, novoCPF) != lClientes.end() || iCliente == lClientes.end())
        return false;
        
    (*iCliente).alterarCliente(novoNome, novoCPF);    
    return true;
}

bool Listas::excluirCliente(){
    
    if(&(*iCliente)){
        lClientes.erase(iCliente);
        iCliente = lClientes.end();
        --quantidadeClientes;
        return true;
    }
    
    return false;
}

bool Listas::selecionarPaciente(int codigo){
    list<Paciente>::iterator iPaciente = Pesquisa::pesquisarPaciente((*iCliente).getListPaciente(), codigo);
    
    if(iPaciente == (*iCliente).getListPaciente().end())
        return false;
        
    (*iCliente).selecionarPaciente((*iPaciente));
    pacote.setPaciente((*iPaciente));
    return true;
}

void Listas::exibirCarteiraPaciente(){
    (*(*iCliente).getPacienteSelecionado()).getCarteira().consultarCarteira();
}

void Listas::exibirAgendaPaciente(){
    (*(*iCliente).getPacienteSelecionado()).getAgenda().consultarAgenda();
}

void Listas::marcarVacinaAplicada(int pos){
    Paciente paciente = (*(*iCliente).getPacienteSelecionado());
    
    //ItemCarteira *itemCarteira = new ItemCarteira((paciente.getAgenda().excluirItemAgenda(pos)));
    
    /*if(itemCarteira)
        paciente.getCarteira().atualizarCarteira(itemCarteira->getVacina(), itemCarteira->getDataAplicacao());*/
}

void Listas::exibirTodasVacinas(){
    
    for(list<Vacina>::iterator vacinasIter = lVacinas.begin(); vacinasIter != lVacinas.end(); vacinasIter++){
        cout << (*vacinasIter) << endl;
    }
}

bool Listas::adicionarVacinaPacote(){
    pacote.addVacina((*iVacina));
}

bool Listas::removerVacinaPacote(int pos){
    list<Vacina>::iterator vacinaIter = Pesquisa::pesquisarVacinaPos(lVacinas, pos);
    
    if(vacinaIter == lVacinas.end())
        return false;
        
    pacote.removeVacina((*iVacina));
    return true;
}

void Listas::exibirVacinasSugeridas(int idade){
    pacote.sugerirPacote();
    
    cout << "Recomenda-se: " << endl << endl;
    
    pacote.consultarPacote();
}

bool Listas::selecionarVacinaPacote(){
    
    if(iVacina == lVacinas.end() || iCliente == lClientes.end())
        return false;
        
    pacote.selecionarVacina((*iVacina));
    
    return true;
}

bool Listas::buscarVacinaDescricao(string descricao){
    if((iVacina = Pesquisa::pesquisarVacinaDescricao(lVacinas, descricao)) == lVacinas.end())
        return false;
        
    return true;
}

bool Listas::buscarVacinaPreco(double preco){
    if((iVacina = Pesquisa::pesquisarVacinaPreco(lVacinas, preco)) == lVacinas.end())
        return false;
        
    return true;
}

bool Listas::buscarVacinasPos(int pos){
    if((iVacina = Pesquisa::pesquisarVacinaPos(lVacinas, pos)) == lVacinas.end())
        return false;
        
    return true;    
}

bool Listas::inserirNovaVacina(string descricao, int idade, double preco){
    Vacina vacina = Vacina(descricao, idade, preco);
    
    if(Pesquisa::pesquisarVacinaPos(lVacinas, vacina.getPK()) != lVacinas.end())
        return false;
    
    lVacinas.push_back(Vacina(descricao, idade, preco));
    ++quantidadeVacinas;
    return true;
}

bool Listas::inserirNovaDoenca(string descricao, string sintomas, string consequencias, int pk){
    
    if(Pesquisa::pesquisarDoenca(lDoencas, pk) != lDoencas.end())
        return false;
    
    lDoencas.push_back(Doenca(descricao, sintomas, consequencias, pk));
    ++quantidadeDoencas;
    return true;
}

void Listas::excluirVacina(){
    lVacinas.erase(iVacina);
    --quantidadeVacinas;
    iVacina = lVacinas.end();
}

bool Listas::excluirDoenca(){
    
    //Verifica se existe algum registro da doença em alguma vacina.
    for(list<Vacina>::iterator vacinasIter = lVacinas.begin(); vacinasIter != lVacinas.end(); vacinasIter++){
        for(list<Doenca>::iterator doencasIter = (*vacinasIter).getListDoenca().begin(); doencasIter != (*vacinasIter).getListDoenca().end(); doencasIter++){
            if(iDoenca == doencasIter)
                return false;
        }
    }
    
    lDoencas.erase(iDoenca);
    iDoenca = lDoencas.end();
    --quantidadeDoencas;
    return true;
}

void Listas::adicionarPaciente(string nome, Data dataNasc){
    (*iCliente).adicionarPaciente(nome, dataNasc);

}

int  Listas::menuPrincipal(){
    int opcao;
    
    cout << "\t\t\tKATTI & FACELLI VACINAS" << endl << endl
         << "\t1- Secao Clientes" << endl
         << "\t2- Secao Vacinas/Doencas" << endl
         << "\t3- Sair" << endl << endl
         << "Digite o numero da opcao desejada: ";
    cin >> opcao;
    
    return opcao;
}

int Listas::menuSecaoClientes(){
    int opcao;
    
    cout << "\t\t\tKATTI & FACELLI VACINAS - Secao Cliente" << endl << endl
         << "\t1- Buscar clientes" << endl
         << "\t2- Exibir todos os clientes" << endl
         << "\t3- Inserir novo cliente" << endl
         << "\t4- Voltar" << endl
         << "\t5- Sair" << endl
         << "Digite o numero da opcao desejada: ";
    cin >> opcao;
    
    return opcao;
}

int Listas::menuBuscarCliente(){
    int opcao;
    
    cout << "\t\t\tKATTI & FACELLI VACINAS - Secao Cliente" << endl << endl
         << "\t1- Buscar cliente pelo cpf" << endl
         << "\t2- Exibir todos os clientes" << endl
         << "Digite o numero da opcao desejada: ";
    cin >> opcao;
    
    return opcao;
}

int Listas::menuClienteSelecionado(){
    int opcao;
    
    cout << "\t\t\tKATTI E FACELLI VACINA - Secao Cliente" << endl << endl;
    (*iCliente).consultarCliente();
    cout << "\t1- Editar cliente" << endl
         << "\t2- Excluir cliente" << endl
         << "\t3- Secao Pacientes" << endl
         << "\t4- Secao Pacotes" << endl
         << "\t5- Voltar" << endl
         << "\t6- Sair" << endl
         << "Digite o numero da opcao desejada: ";
    cin >> opcao;
    
    return opcao;
}

int Listas::menuSecaoPacientes(){
    int opcao;
    
    cout << "\t\t\tKATTI & FACELLI VACINAS - Secao Pacientes" << endl << endl;
    (*iCliente).consultarCliente();
    cout << "\t1- Buscar pacientes" << endl
         << "\t2- Exibir todos os pacientes" << endl
         << "\t3- Adicionar paciente" << endl
         << "\t4- Voltar" << endl
         << "\t5- Sair" << endl
         << "Digite o numero da opcao desejada: ";
    cin >> opcao;
    
    return opcao;
}

int Listas::menuPacienteSelecionado(){
    int opcao;
    
    cout << "\t\t\tKATTI & FACELLI VACINAS - Secao Pacientes" << endl << endl;
    (*(*iCliente).getPacienteSelecionado()).consultarPaciente();
    cout << endl << "\t1- Editar paciente" << endl
         << "\t2- Excluir paciente" << endl
         << "\t3- Carteira de vacinacao do paciente" << endl
         << "\t4- Agenda do paciente" << endl
         << "\t5- Voltar" << endl
         << "\t6- Sair" << endl
         << "Selecione o numero da opcao desejada: ";
    cin >> opcao;
    
    return opcao;
}

int Listas::menuCarteira(){
    cout << "\t\t\tKATTI & FACELLI VACINAS - Carteira de vacinacao" << endl << endl;
    (*(*iCliente).getPacienteSelecionado()).getCarteira().consultarCarteira();
}

int Listas::menuAgenda(){
    cout << "\t\t\tKATTI & FACELLI VACINAS - Agenda" << endl << endl;
    (*(*iCliente).getPacienteSelecionado()).getAgenda().consultarAgenda();
}

int Listas::menuExibirTodosPacientes(){
    int opcao;
    list<Paciente>::iterator p;
    
    cout << "\t\t\tKATTI & FACELLI VACINAS - Secao Pacientes" << endl << endl;
    (*iCliente).listarPacientes();
    cout << "Digite o numero do paciente desejado: ";
    cin >> opcao;
    
    if((p = Pesquisa::pesquisarPacientePos((*iCliente).getListPaciente(), opcao)) == (*iCliente).getListPaciente().end())
        return false;
        
    (*iCliente).selecionarPaciente((*p));
    return true;
}

int Listas::menuSecaoPacotes(){
    int opcao;
    
    cout << "\t\t\tKATTI & FACELLI - Secao Pacotes" << endl << endl;
    (*iCliente).listarPacientes();
    cout << endl << "\tDigite o numero do paciente: ";
    cin >> opcao;
    
    return opcao;
}

int Listas::menuSelecionarPaciente(){
    int opcao;
    
    cout << "\t\t\tKATTI & FACELLI VACINAS - secao Pacotes" << endl << endl
         << "\t1- Adicionar vacina ao pacote" << endl
         << "\t2- Remover vacina do pacote" << endl
         << "\t3- Calcular preco total do pacote" << endl
         << "\t4- Vacinas sugeridas" << endl
         << "\t5- Voltar" << endl
         << "\t6- Sair" << endl
         << "Selecione o numero da opcao desejada: ";
    cin >> opcao;
    
    return opcao;
}

int Listas::menuAdicionarRemoverVacinaPacote(){
    int opcao;
    
    cout << "\t\t\tKATTI & FACELLI VACINAS - Secao Pacotes" << endl << endl
         << "\t1- Buscar vacina por codigo" << endl
         << "\t2- Buscar vacina por descricao" << endl
         << "\t3- Buscar vacina por preco" << endl
         << "\t4- Voltar" << endl
         << "Digite o numero da opcao desejada: ";
    cin >> opcao;
    
    return opcao;
}

int Listas::menuVacinasSugeridas(int idade){
    int opcao;
    
    cout << "KATTI & FACELLI VACINAS - Secao Pacotes" << endl << endl;
    exibirVacinasSugeridas(idade);
    cout << endl << "\t1- Selecionar vacina para adicionar ao pacote" << endl
         << "\t2- Adicionar todas as vacinas ao pacote" << endl
         << "\t3- Voltar" << endl
         << "Digite o numero da opcao desejada: ";
    cin >> opcao;
    
    return opcao;
}

bool Listas::menuExibirTodosClientes(){
    int opcao;
    
    cout << "\t\t\tKATTI & FACELLI VACINAS - Secao Clientes" << endl << endl;
    exibirTodosClientes();
    cout << endl << "Selecione o numero do cliente: ";
    cin >> opcao;
    
    return selecionarClientePos(opcao - 1);
}

int Listas::menuSecaoVacinasDoencas(){
    int opcao;
    
    cout << "\t\t\tKATTI & FACELLI VACINAS - Secao Vacinas/Doencas" << endl << endl
         << "\t1- Buscar vacinas" << endl
         << "\t2- Exibir todas vacinas" << endl
         << "\t3- Inserir nova vacina" << endl
         << "\t4- Cadastrar nova doenca" << endl
         << "\t5- Editar doenca" << endl
         << "\t6- Excluir doenca" << endl
         << "\t7- Voltar" << endl
         << "\t8- Sair" << endl
         << "Digite o numero da opcao desejada: ";
    cin >> opcao;
    
    return opcao;
}

int Listas::menuBuscarVacinas(){
    int opcao;
    
    cout << "\t\t\tKATTI & FACELLI VACINAS - Secao Vacinas/Doencas" << endl << endl
         << "\t1- Buscar vacina" << endl
         << "\t2- Exibir todas as vacinas" << endl
         << "\t3- Remover doenca" << endl
         << "\t4- Adicionar doenca" << endl
         << "\t5- Excluir vacinas" << endl
         << "\t6- Voltar" << endl
         << "Digite o numero da opcao desejada: ";
    cin >> opcao;
    
    return opcao;
}

int Listas::menuExibirTodasVacinas(){
    int opcao;
    
    cout << "\t\t\tKATTI & FACELLI VACINAS - Secao Vacinas/Doencas" << endl << endl;
    exibirTodasVacinas();
    cout << "Digite o numero da vacina: ";
    cin >> opcao;
    
    return opcao;
}

void Listas::menuInserirNovoCliente(){
    string nome;
    string cpf;
    
    cout << endl << "\tDigite o nome do cliente: ";
    do{
        getline(cin, nome);
    }while(!nome.size());
    
    while(true){
        cout << "\tDigite o cpf do cliente: ";
        cin >> cpf;
        
        if(Cliente::cpfValido(cpf))
            break;
            
        cout << "\tCPF invalido" << endl << endl;
    }
    
    inserirCliente(nome, cpf);
}

bool Listas::menuBuscarClienteCPF(){
    string cpf;
    
    cout << "\tDigite o cpf do cliente: ";
    cin >> cpf;
    
    return selecionarCliente(cpf);
}

void Listas::menuEditarCliente(){
    string nome, cpf;
    
    cout << "\tDigite o nome do cliente: ";
    cin >> nome;
    
    while(true){
        cout << "\tDigite o cpf do cliente: ";
        cin >> cpf;
        
        if(Cliente::cpfValido(cpf))
            break;
            
        cout << "\tCPF invalido" << endl << endl;
    }
    
    (*iCliente).alterarCliente(nome, cpf);
}

void Listas::menuAdicionarPaciente(){
    string nome;
    int dia, mes, ano;
    
    cout << "\tDigite o nome do paciente: ";
    do{
        getline(cin, nome);
    }while(!nome.size());
    
    cout << "\tDigite a data de nascomento do pasciente (dd mm aaaa): ";
    cin >> dia >> mes >> ano;
    
    adicionarPaciente(nome, Data(dia, mes, ano));
    
}

bool Listas::menuBuscarPacientes(){
    int codigo;
    list<Paciente>::iterator p;
    
    cout << "\tDigite o codigo do paciente: ";
    cin >> codigo;
    
    if((p = Pesquisa::pesquisarPaciente((*iCliente).getListPaciente(), codigo)) == (*iCliente).getListPaciente().end())
        return false;

    (*iCliente).selecionarPaciente((*p));
        return true;
}

void Listas::menuEditarPaciente(){
    string nome;
    int dia, mes, ano;
    
    cout << "\tDigite o nome do paciente: ";
    cin >> nome;
    
    cout << "\tDigite a data de nascimento (dd mm aaaa): ";
    cin >> dia >> mes >> ano;
    
    (*(*iCliente).getPacienteSelecionado()).alterarPaciente(nome, Data(dia, mes, ano));
}

void Listas::excluirPaciente(){
    (*iCliente).excluirPaciente();
}

ostream &operator<< (ostream &out, Listas &lista){
    list<Vacina>::iterator iteradorVacina = lista.lVacinas.begin();
    list<Doenca>::iterator iteradorDoenca = lista.lDoencas.begin();
    list<Cliente>::iterator iteradorCliente = lista.lClientes.begin();
    
    out << lista.quantidadeVacinas << endl;
    
    while(iteradorVacina != lista.lVacinas.end() ){
        out << (*iteradorVacina);
        ++iteradorVacina;
    }
    
    out << lista.quantidadeDoencas << endl;
    
    while(iteradorDoenca != lista.lDoencas.end()){
        out << (*iteradorDoenca);
        iteradorDoenca++;
    }
    
    out << lista.quantidadeClientes << endl;
    
    while(iteradorCliente != lista.lClientes.begin()){
        out << (*iteradorCliente); 
    }
}

istream &operator>> (istream &in, Listas &lista){
    in >> lista.quantidadeVacinas;
    in.ignore();
    
    Vacina auxVacina;
    Doenca auxDoenca;
    Cliente auxCliente;
    
    int aux = lista.quantidadeVacinas;
    
    while(aux){
        aux--;
        in >> auxVacina; 
        lista.lVacinas.push_back(auxVacina);
    }	
    
    in >> lista.quantidadeDoencas;
    in.ignore();
    
    aux = lista.quantidadeDoencas;
    
    while(aux){
        aux--;
        in >> auxDoenca;
        lista.lDoencas.push_back(auxDoenca);
    }
    
    in >> lista.quantidadeClientes;
    in.ignore();
    
    aux = lista.quantidadeClientes;
    
    while(aux){
        aux--;
        in >> auxCliente;
        lista.lClientes.push_back(auxCliente);
    }
}

void Listas::carregarArquivos(){
    
    ofstream gravar("pacientes.dat");
    
    for(list<Paciente>::iterator pacientesIter = (*iCliente).getListPaciente().begin(); pacientesIter != (*iCliente).getListPaciente().end(); pacientesIter++)
        gravar << (*pacientesIter) << endl;
}
